home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Tools / modulator / genmodule.py < prev    next >
Text File  |  1996-03-12  |  4KB  |  162 lines

  1. #
  2. # Genmodule - A python program to help you build (template) modules.
  3. #
  4. # Usage:
  5. #
  6. # o = genmodule.object()
  7. # o.name = 'dwarve object'
  8. # o.abbrev = 'dw'
  9. # o.funclist = ['new', 'dealloc', 'getattr', 'setattr']
  10. # o.methodlist = ['dig']
  11. #
  12. # m = genmodule.module()
  13. # m.name = 'beings'
  14. # m.abbrev = 'be'
  15. # m.methodlist = ['newdwarve']
  16. # m.objects = [o]
  17. #
  18. # genmodule.write(sys.stdout, m)
  19. #
  20. import sys
  21. import os
  22. import varsubst
  23. import string
  24.  
  25. error = 'genmodule.error'
  26.  
  27. #
  28. # Names of functions in the object-description struct.
  29. #
  30. FUNCLIST = ['new', 'tp_dealloc', 'tp_print', 'tp_getattr', 'tp_setattr',
  31.         'tp_compare', 'tp_repr', 'tp_hash', 'tp_call', 'tp_str']
  32. TYPELIST = ['tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'structure']
  33.  
  34. #
  35. # writer is a base class for the object and module classes
  36. # it contains code common to both.
  37. #
  38. class writer:
  39.     def __init__(self):
  40.     self._subst = None
  41.  
  42.     def makesubst(self):
  43.     if not self._subst:
  44.         if not self.__dict__.has_key('abbrev'):
  45.         self.abbrev = self.name
  46.         self.Abbrev = string.upper(self.abbrev[0])+self.abbrev[1:]
  47.         subst = varsubst.Varsubst(self.__dict__)
  48.         subst.useindent(1)
  49.         self._subst = subst.subst
  50.  
  51.     def addcode(self, name, fp):
  52.     ifp = self.opentemplate(name)
  53.     self.makesubst()
  54.     d = ifp.read()
  55.     d = self._subst(d)
  56.     fp.write(d)
  57.  
  58.     def opentemplate(self, name):
  59.     for p in sys.path:
  60.         fn = os.path.join(p, name)
  61.         if os.path.exists(fn):
  62.         return open(fn, 'r')
  63.         fn = os.path.join(p, 'Templates')
  64.         fn = os.path.join(fn, name)
  65.         if os.path.exists(fn):
  66.         return open(fn, 'r')
  67.     raise error, 'Template '+name+' not found for '+self._type+' '+ \
  68.                  self.name
  69.     
  70. class module(writer):
  71.     _type = 'module'
  72.  
  73.     def writecode(self, fp):
  74.     self.addcode('copyright', fp)
  75.     self.addcode('module_head', fp)
  76.     for o in self.objects:
  77.         o.writehead(fp)
  78.     for o in self.objects:
  79.         o.writebody(fp)
  80.     new_ml = ''
  81.     for fn in self.methodlist:
  82.         self.method = fn
  83.         self.addcode('module_method', fp)
  84.         new_ml = new_ml + (
  85.               '{"%s",\t(PyCFunction)%s_%s,\tMETH_VARARGS,\t%s_%s__doc__},\n'
  86.               %(fn, self.abbrev, fn, self.abbrev, fn))
  87.     self.methodlist = new_ml
  88.     self.addcode('module_tail', fp)
  89.  
  90. class object(writer):
  91.     _type = 'object'
  92.     def __init__(self):
  93.     self.typelist = []
  94.     self.methodlist = []
  95.     self.funclist = ['new']
  96.     writer.__init__(self)
  97.  
  98.     def writecode(self, fp):
  99.     self.addcode('copyright', fp)
  100.     self.writehead(fp)
  101.     self.writebody(fp)
  102.  
  103.     def writehead(self, fp):
  104.     self.addcode('object_head', fp)
  105.  
  106.     def writebody(self, fp):
  107.     new_ml = ''
  108.     for fn in self.methodlist:
  109.         self.method = fn
  110.         self.addcode('object_method', fp)
  111.         new_ml = new_ml + (
  112.               '{"%s",\t(PyCFunction)%s_%s,\tMETH_VARARGS,\t%s_%s__doc__},\n'
  113.               %(fn, self.abbrev, fn, self.abbrev, fn))
  114.     self.methodlist = new_ml
  115.     self.addcode('object_mlist', fp)
  116.  
  117.     # Add getattr if we have methods
  118.     if self.methodlist and not 'tp_getattr' in self.funclist:
  119.         self.funclist.insert(0, 'tp_getattr')
  120.         
  121.     for fn in FUNCLIST:
  122.         setattr(self, fn, '0')
  123.  
  124.     #
  125.     # Special case for structure-access objects: put getattr in the
  126.     # list of functions but don't generate code for it directly,
  127.     # the code is obtained from the object_structure template.
  128.     # The same goes for setattr.
  129.     #
  130.     if 'structure' in self.typelist:
  131.         if 'tp_getattr' in self.funclist:
  132.         self.funclist.remove('tp_getattr')
  133.         if 'tp_setattr' in self.funclist:
  134.         self.funclist.remove('tp_setattr')
  135.         self.tp_getattr = self.abbrev + '_getattr'
  136.         self.tp_setattr = self.abbrev + '_setattr'
  137.     for fn in self.funclist:
  138.         self.addcode('object_'+fn, fp)
  139.         setattr(self, fn, '%s_%s'%(self.abbrev, fn[3:]))
  140.     for tn in TYPELIST:
  141.         setattr(self, tn, '0')
  142.     for tn in self.typelist:
  143.         self.addcode('object_'+tn, fp)
  144.         setattr(self, tn, '&%s_%s'%(self.abbrev, tn[3:]))
  145.     self.addcode('object_tail', fp)
  146.  
  147. def write(fp, obj):
  148.     obj.writecode(fp)
  149.  
  150. if __name__ == '__main__':
  151.     o = object()
  152.     o.name = 'dwarve object'
  153.     o.abbrev = 'dw'
  154.     o.funclist = ['new', 'tp_dealloc']
  155.     o.methodlist = ['dig']
  156.     m = module()
  157.     m.name = 'beings'
  158.     m.abbrev = 'be'
  159.     m.methodlist = ['newdwarve']
  160.     m.objects = [o]
  161.     write(sys.stdout, m)
  162.